package com.cwg.dict.service.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.FloatControl.Type;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cwg.dict.service.Speaker;

public class SpeakerImpl implements Speaker {

	private FileHelper	fileHelper;
	private Logger		logger	= LoggerFactory.getLogger(SpeakerImpl.class);

	public FileHelper getFileHelper() {
		return fileHelper;
	}

	public void playAudioFile(File soundFile) {
		try {
			AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
			playAudioStream(audioInputStream);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void playAudioStream(AudioInputStream audioInputStream) {
		AudioFormat audioFormat = audioInputStream.getFormat();

		Info info = new Info(SourceDataLine.class, audioFormat);
		if (!AudioSystem.isLineSupported(info)) {
			return;
		}

		try {
			SourceDataLine dataLine = (SourceDataLine) AudioSystem.getLine(info);
			dataLine.open(audioFormat);
			if (dataLine.isControlSupported(Type.MASTER_GAIN)) {
				// TODO: no idea why need this code in here, maybe it can be remove.
				// do no thing
			}
			dataLine.start();

			int bufferSize = (int) audioFormat.getSampleRate() * audioFormat.getFrameSize();
			byte[] buffer = new byte[bufferSize];

			try {
				int bytesRead = 0;
				while (bytesRead >= 0) {
					bytesRead = audioInputStream.read(buffer, 0, buffer.length);
					if (bytesRead >= 0) {
						dataLine.write(buffer, 0, bytesRead);
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			dataLine.drain();
			dataLine.close();
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void pronounce(String word) {
		try {
			File soundFile = fileHelper.getSoundFile(word);
			playAudioFile(soundFile);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			logger.warn("sound file [{}] not found", word);
		}
	}

	public void setFileHelper(FileHelper fileHelper) {
		this.fileHelper = fileHelper;
	}
}